#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDateTime>
#include <QFileDialog>
#include <QMessageBox>


// 写入缓冲区大小
const int WRITE_BUFFER_SIZE = 64 * 1024 * 1024; // 64MB

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , m_socket(nullptr)
    , m_dataFile(nullptr)
    , m_statsTimer(nullptr)
    , m_totalBytesReceived(0)
    , m_lastBytesReceived(0)
    , m_statCount(0)
    , m_isConnected(false)
    , m_isReceiving(false)
{
    ui->setupUi(this);

    // 设置窗口标题
    setWindowTitle("TCP文件接收客户端");

    // 初始化socket
    m_socket = new QTcpSocket(this);

    // 初始化统计定时器
    m_statsTimer = new QTimer(this);

    // 连接信号槽
    connect(m_socket, &QTcpSocket::connected, this, &MainWindow::onSocketConnected);
    connect(m_socket, &QTcpSocket::disconnected, this, &MainWindow::onSocketDisconnected);
    connect(m_socket, &QTcpSocket::readyRead, this, &MainWindow::onSocketReadyRead);
    connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
            this, &MainWindow::onSocketError);

//    connect(m_statsTimer, &QTimer::timeout, this, &MainWindow::updateStats);

    // 设置默认值
    ui->ipEdit->setText("192.168.1.106");
//        ui->ipEdit->setText("127.0.0.1");
    ui->portEdit->setText("21");

    // 初始状态
    enableControls(false, false);

    appendLog("程序已启动，请输入服务器信息");
}

MainWindow::~MainWindow()
{
    if (m_socket->state() == QAbstractSocket::ConnectedState) {
        m_socket->disconnectFromHost();
    }

    if (m_dataFile) {
        m_dataFile->close();
        delete m_dataFile;
    }

    delete ui;
}

void MainWindow::on_connectButton_clicked()
{
    if (m_isConnected) {
        return;
    }

    m_serverIP = ui->ipEdit->text().trimmed();
    m_port = ui->portEdit->text().toInt();

    if (m_serverIP.isEmpty()) {
        QMessageBox::warning(this, "输入错误", "请输入服务器IP地址");
        return;
    }

    if (m_port <= 0 || m_port > 65535) {
        QMessageBox::warning(this, "输入错误", "请输入有效的端口号 (1-65535)");
        return;
    }

    // 重置统计信息
    resetStats();

    // 连接服务器
    appendLog(QString("正在连接服务器 %1:%2...").arg(m_serverIP).arg(m_port));

    // 设置socket选项进行优化
    m_socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
    m_socket->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption, 64 * 1024 * 1024);

    m_socket->connectToHost(m_serverIP, m_port);

    ui->connectButton->setEnabled(false);
}

void MainWindow::on_disconnectButton_clicked()
{
    if (m_socket->state() == QAbstractSocket::ConnectedState) {
        m_socket->disconnectFromHost();
    }

    m_isConnected = false;
    m_isReceiving = false;
    m_statsTimer->stop();

    // 最后刷新缓冲区
    flushWriteBuffer();

    if (m_dataFile) {
        m_dataFile->close();
        delete m_dataFile;
        m_dataFile = nullptr;
    }

    enableControls(false, false);

    appendLog("已断开连接");
}

void MainWindow::on_startReceiveButton_clicked()
{
    if (!m_isConnected) {
        QMessageBox::warning(this, "错误", "请先连接服务器");
        return;
    }

    if (m_isReceiving) {
        return;
    }

    QString filePath = ui->filePathEdit->text().trimmed();
    if (filePath.isEmpty()) {
#if 0
        // 弹出文件选择对话框
        filePath = QFileDialog::getSaveFileName(this, "选择保存文件", "received_file.bin", "所有文件 (*.*)");
        if (filePath.isEmpty()) {
            return;
        }
        ui->filePathEdit->setText(filePath);
 #else
        // 如果文件路径为空，则调用浏览按钮的功能
        on_browseButton_clicked();
        filePath = ui->filePathEdit->text().trimmed();
        if (filePath.isEmpty()) {
            return; // 用户取消了选择
        }
#endif
    }

    // 初始化文件
    if (!initializeFile(filePath)) {
        return;
    }

    m_isReceiving = true;
    enableControls(true, true);

    // 启动统计定时器
    m_statsTimer->start(1000); // 每秒更新一次
    m_speedTimer.start();

    appendLog("开始接收数据...");
}

void MainWindow::on_browseButton_clicked()
{
    // 弹出文件保存对话框
      QString filePath = QFileDialog::getSaveFileName(
          this,
          "选择保存文件",
          "received_file.bin",
          "所有文件 (*.*)"
      );

      if (!filePath.isEmpty()) {
          ui->filePathEdit->setText(filePath);
          appendLog(QString("已选择保存路径: %1").arg(filePath));
      }
}

void MainWindow::onSocketConnected()
{
    m_isConnected = true;
    enableControls(true, false);

    appendLog("连接服务器成功");

    // 更新界面
    ui->statusLabel->setText("状态: 已连接");
}

void MainWindow::onSocketDisconnected()
{
    m_isConnected = false;
    m_isReceiving = false;
    m_statsTimer->stop();

    // 最后刷新缓冲区
    flushWriteBuffer();

    if (m_dataFile) {
        m_dataFile->close();
        delete m_dataFile;
        m_dataFile = nullptr;
    }

    enableControls(false, false);
    ui->statusLabel->setText("状态: 已断开连接");

    appendLog("与服务器断开连接");
}

void MainWindow::onSocketReadyRead()
{
    if (!m_isConnected) {
        return;
    }

    // 读取所有可用数据
    QByteArray data = m_socket->readAll();
    if (data.isEmpty()) {
        return;
    }

    // 如果正在接收数据，则保存到文件
    if (m_isReceiving && m_dataFile) {
//        m_totalBytesReceived += data.size();

        // 将数据添加到写入缓冲区
        if (m_writeBuffer.size() + data.size() <= WRITE_BUFFER_SIZE) {
            m_writeBuffer.append(data);
        } else {
            // 缓冲区不足，先刷新
            flushWriteBuffer();
            m_writeBuffer.append(data);
        }

    } else {
        // 如果不处于接收状态，只是读取数据但不保存
        appendLog(QString("接收到 %1 字节数据，但未开始保存").arg(data.size()));
    }
}

void MainWindow::onSocketError(QAbstractSocket::SocketError error)
{
    QString errorStr;
    switch (error) {
    case QAbstractSocket::ConnectionRefusedError:
        errorStr = "连接被拒绝";
        break;
    case QAbstractSocket::RemoteHostClosedError:
        errorStr = "远程主机关闭连接";
        break;
    case QAbstractSocket::HostNotFoundError:
        errorStr = "找不到服务器";
        break;
    case QAbstractSocket::SocketTimeoutError:
        errorStr = "连接超时";
        break;
    case QAbstractSocket::NetworkError:
        errorStr = "网络错误";
        break;
    default:
        errorStr = QString("Socket错误: %1").arg(error);
        break;
    }

    appendLog(QString("网络错误: %1").arg(errorStr));

    // 重置状态
    m_isConnected = false;
    m_isReceiving = false;
    m_statsTimer->stop();

    enableControls(false, false);
    ui->statusLabel->setText("状态: 连接失败");
}

//void MainWindow::updateStats()
//{
//    if (!m_isReceiving) {
//        return;
//    }

//    // 计算当前速度
//    double elapsed = m_speedTimer.elapsed() / 1000.0; // 转换为秒
//    if (elapsed <= 0) {
//        return;
//    }

//    double currentSpeed = (m_totalBytesReceived - m_lastBytesReceived) / (1024.0 * 1024.0); // MB/s

//    // 更新统计
//    m_avgSpeed = (m_avgSpeed * m_statCount + currentSpeed) / (m_statCount + 1);
//    if (currentSpeed > m_maxSpeed) m_maxSpeed = currentSpeed;
//    if (currentSpeed < m_minSpeed && currentSpeed > 0) m_minSpeed = currentSpeed;
//    m_statCount++;

//    // 更新界面
//    ui->speedLabel->setText(QString("速度: %1 MB/s").arg(currentSpeed, 0, 'f', 2));
//    ui->avgSpeedLabel->setText(QString("平均: %1 MB/s").arg(m_avgSpeed, 0, 'f', 2));
//    ui->maxSpeedLabel->setText(QString("最大: %1 MB/s").arg(m_maxSpeed, 0, 'f', 2));
//    ui->totalLabel->setText(QString("总量: %1 MB").arg(m_totalBytesReceived / (1024.0 * 1024.0), 0, 'f', 2));

//    m_lastBytesReceived = m_totalBytesReceived;
//    m_speedTimer.restart();
//}

void MainWindow::flushWriteBuffer()
{
    if (m_writeBuffer.isEmpty() || !m_dataFile) {
        return;
    }

    // 写入文件
    qint64 written = m_dataFile->write(m_writeBuffer);
    if (written != m_writeBuffer.size()) {
        appendLog(QString("文件写入错误: 期望写入 %1 字节，实际写入 %2 字节")
                  .arg(m_writeBuffer.size()).arg(written));
    }

    m_writeBuffer.clear();
    m_dataFile->flush();
}

void MainWindow::appendLog(const QString &message)
{
    QString timestamp = QDateTime::currentDateTime().toString("hh:mm:ss");
    ui->logTextEdit->appendPlainText(QString("[%1] %2").arg(timestamp, message));

    // 自动滚动到底部
    QTextCursor cursor = ui->logTextEdit->textCursor();
    cursor.movePosition(QTextCursor::End);
    ui->logTextEdit->setTextCursor(cursor);
}

void MainWindow::resetStats()
{
    m_totalBytesReceived = 0;
    m_lastBytesReceived = 0;
    m_statCount = 0;
    m_writeBuffer.clear();
}

bool MainWindow::initializeFile(const QString &filePath)
{
    m_dataFile = new QFile(filePath);
    if (!m_dataFile->open(QIODevice::WriteOnly)) {
        QMessageBox::warning(this, "文件错误",
                           QString("无法创建文件: %1\n%2").arg(filePath).arg(m_dataFile->errorString()));
        delete m_dataFile;
        m_dataFile = nullptr;
        return false;
    }

    appendLog(QString("文件已创建: %1").arg(filePath));
    return true;
}

void MainWindow::enableControls(bool connected, bool receiving)
{
    ui->connectButton->setEnabled(!connected);
    ui->disconnectButton->setEnabled(connected);
    ui->startReceiveButton->setEnabled(connected && !receiving);
    ui->browseButton->setEnabled(!receiving); // 浏览按钮在接收时禁用

    // 文件路径编辑框在未开始接收时可编辑
    ui->filePathEdit->setEnabled(!receiving);

    // 更新状态标签
    if (!connected) {
        ui->statusLabel->setText("状态: 未连接");
    } else if (connected && !receiving) {
        ui->statusLabel->setText("状态: 已连接，等待开始接收");
    } else if (connected && receiving) {
        ui->statusLabel->setText("状态: 已连接，接收数据中...");
    }
}

